# @File    : upgrade.py
# @Project : Airtest_JBL
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
from poco.exceptions import PocoNoSuchNodeException
from exception.catch_exception import ExceptionUtil
from exception.custom_exception import ElectricException
from common.logUtil import info_a, warning_a
from common.operate import OperateUtil
from common.yamlUtil import YamlUtil
from airtest.core.api import *
import logging
logging.getLogger("airtest").setLevel(logging.ERROR)


class Upgrade:

    # 读取存储的耳机版本号
    location = YamlUtil("data.yaml").read_yaml()
    h_version = location['h_version']
    l_version = location['l_version']
    ota_times = location['ota_times']
    test_device = location['device']

    poco = AndroidUiautomationPoco()
    ex = ExceptionUtil(poco)
    operate = OperateUtil()

    # 获取屏幕宽和高
    width = poco.get_screen_size()[0]
    height = poco.get_screen_size()[1]

    earbud = "^耳机：.*$"
    case = "^充电盒：.*$"
    schedule = "^剩余.*"
    a_version = "应用版本.*"
    process = ".*%"
    transmission = "正在传输.*"

    pass_num = 0
    fail_num = 0
    fail_list = []

    # 正常升降级流程
    def ota_updown_grade(self, num):
        version = self.check_version()
        for i in range(1, int(num)+1):
            try:
                start_time = time.time()
                for _ in range(2):
                    self.page_back()
                    self.select_version(version, self.test_device)
                    self.ota_start(i, version)
                    self.ota_process(i, version)
                    if self.test_device == "耳机":
                        version = self.poco(textMatches=f"{self.earbud}").get_text()[5:]
                    elif self.test_device == "充电盒":
                        version = self.poco(textMatches=f"{self.case}").get_text()[6:]
                    sleep(1)
                end_time = time.time()
                total_time = end_time - start_time
                minutes, seconds = divmod(total_time, 60)
                info_a(f"第 {i} 次升降级耗时: {int(minutes)} 分 {int(seconds)} 秒")
            except ElectricException:
                self.fail_num += 1
                self.fail_list.append(i)
                warning_a(f"第 {i} 次测试时耳机电量低于50%")
                break
            except PocoNoSuchNodeException:
                self.fail_num += 1
                self.fail_list.append(i)
                warning_a("未找到元素，请重新执行程序!")
                break
        sleep(2)
        info_a(f"测试完成, 共压测 {i} 次, 其中 PASS {self.pass_num} 次, FAIL {self.fail_num} 次, FAIL的轮数为{self.fail_list}")
        self.fail_list.clear()

    # 查看耳机版本号
    def check_version(self):
        other = self.poco(text="Others").wait(15)
        if other.exists():
            other.click()
            swipe((self.width * 0.5, self.height * 0.88), (self.width * 0.5, self.height * 0.6))
            self.poco(text="支持").click()
            if self.test_device == "耳机":
                version = self.poco(textMatches=f"{self.earbud}").get_text()[5:]
                info_a(f"当前耳机版本为: {version}")
            else:
                version = self.poco(textMatches=f"{self.case}").get_text()[6:]
                info_a(f"当前充电盒版本为: {version}")
            return version

    # 查看版本号后前往选择版本页面
    def page_back(self):
        self.poco("android.widget.FrameLayout").offspring("jbl.stc.com.debug:id/supportRelativeLayout").offspring(
            "jbl.stc.com.debug:id/leftImgView").click()

        self.poco("jbl.stc.com.debug:id/leftImgView").click()

        self.poco(name="jbl.stc.com.debug:id/image_view_dashboard_white_menu", desc="TODO").click()

        app_version = self.poco(textMatches=f"{self.a_version}").attr("pos")
        pos_width = app_version[0]
        pos_height = app_version[1]
        touch((self.width * pos_width, self.height * pos_height), times=14)
        sleep(1)
        if self.poco("jbl.stc.com.debug:id/btExplore").exists():
            keyevent("BACK")
        checkbox = self.poco("jbl.stc.com.debug:id/checkBoxFOta")
        if checkbox.attr("checked"):
            self.poco("jbl.stc.com.debug:id/buttonSelect").click()
        else:
            checkbox.click()
            self.poco("jbl.stc.com.debug:id/buttonSelect").click()

        self.poco("显示根目录").click()
        sleep(1)
        download = self.poco(text="下载内容", name="android:id/title"
                             ).parent().sibling().child("android:id/icon").attr("pos")
        d_pos_width = download[0]
        d_pos_height = download[1]
        touch(v=(self.width * d_pos_width, self.height * d_pos_height))

    # 根据当前版本选择耳机升级版本
    def select_version(self, version, test_device):
        if version == self.l_version:
            self.poco(text=f"{self.location['advanced_version_package']}").click()
            if test_device == "耳机":
                self.poco(textMatches=f"{self.location['ota_package']}").click()
            elif test_device == "充电盒":
                self.poco(textMatches=f"{self.location['case_package']}").click()
        elif version == self.h_version:
            self.poco(text=f"{self.location['low_version_package']}").click()
            if test_device == "耳机":
                self.poco(textMatches=f"{self.location['ota_package']}").click()
            elif test_device == "充电盒":
                self.poco(textMatches=f"{self.location['case_package']}").click()
        # 返回
        self.poco("jbl.stc.com.debug:id/image_view_back").click()
        sleep(1)
        # self.poco("jbl.stc.com.debug:id/image_view_info_a_back").click()
        # self.poco("jbl.stc.com.debug:id/image_view_info_a_back").click()
        self.operate.back()

    def ota_start(self, i, version):
        # touch(v=(550, 715))
        self.poco("android.widget.FrameLayout").offspring("jbl.stc.com.debug:id/grid_view_dashboard").child(
            "android.widget.LinearLayout")[0].offspring(
            "jbl.stc.com.debug:id/image_view_item_connected_before_device_icon").click()
        self.poco(text="Others").click()
        swipe((self.width * 0.5, self.height * 0.88), (self.width * 0.5, self.height * 0.6))
        self.poco(text="支持").click()
        if self.test_device == "耳机":
            self.poco(text="软件").click()
        else:
            self.poco(text="智能保护盒").click()
        self.poco(text="更新").refresh()
        self.poco(text="更新").click()
        if version == self.h_version:
            info_a(f"第 {i} 次降级开始...")
        elif version == self.l_version:
            info_a(f"第 {i} 次升级开始...")

    # 升级过程
    def ota_process(self, i, version):
        while True:
            if self.poco(text="耳机电量需超过 50%。").exists():
                raise ElectricException
            if self.poco(textMatches=f"{self.transmission}").exists():
                self.check_process()
            if not self.poco(textMatches=f"{self.schedule}").exists():
                if self.poco(text="更新成功").exists():
                    self.poco(text="完成").click()
                    if self.test_device == "耳机":
                        version = self.poco(textMatches=f"{self.earbud}").get_text()[5:]
                    elif self.test_device == "充电盒":
                        version = self.poco(textMatches=f"{self.case}").get_text()[6:]
                    self.check_after_version(i, version)
                    break
                # 更新失败处理
                elif self.poco(text="更新失败").exists():
                    self.poco(text="取消").click()
                    sleep(2)
                    version = self.ex.check_fail()
                    self.check_after_version(i, version)
                    self.fail_num += 1
                    self.fail_list.append(i)
                    break
                elif self.poco(text="General").exists():
                    self.poco(text="Others").click()
                    swipe((self.width * 0.5, self.height * 0.88), (self.width * 0.5, self.height * 0.6))
                    self.poco(text="支持").click()
                    if self.test_device == "耳机":
                        version = self.poco(textMatches=f"{self.earbud}").get_text()[5:]
                    elif self.test_device == "充电盒":
                        version = self.poco(textMatches=f"{self.case}").get_text()[6:]
                    self.check_after_version(i, version)
                    break
            if self.poco(text="重试").exists():
                self.poco(text="重试").click()
                sleep(1)
                self.poco(text="更新").click()

    # 根据升级后的版本来进行后续操作
    def check_after_version(self, i, version):
        if version == self.h_version:
            info_a(f"第 {i} 次升级成功...")
            sleep(2)
            info_a(f"第 {i} 次升级后的版本为: {version}")
            self.pass_num += 1
        elif version == self.l_version:
            stop_app("jbl.stc.com.debug")
            time.sleep(2)
            start_app("jbl.stc.com.debug")
            other = self.poco(text="Others").wait(30)
            if other.exists():
                other.click()
                swipe((self.width * 0.5, self.height * 0.88), (self.width * 0.5, self.height * 0.6))
                self.poco(text="支持").click()
                if self.test_device == "耳机":
                    version = self.poco(textMatches=f"{self.earbud}").get_text()[5:]
                elif self.test_device == "充电盒":
                    version = self.poco(textMatches=f"{self.case}").get_text()[6:]
                if version == self.l_version:
                    info_a(f"第 {i} 次降级成功...")
                    sleep(2)
                    info_a(f"第 {i} 次降级后的版本为: {version}")

    def check_process(self):
        pro = YamlUtil("process.txt")
        while True:
            process = self.poco(textMatches=f"{self.process}").get_text()[:-1]
            if process == "100":
                pro.overwrite(process)
                break
            else:
                pro.overwrite(process)



